/**
 * @file Channel.cpp
 * @brief Channel类实现 - 处理文件描述符的I/O事件
 * @details 实现了Channel类的方法，包括事件处理、回调函数调用等
 */

#include "../include/channel.h"
#include "../include/event_loop.h"
#include "../include/logger.h"
#include <sys/epoll.h>
 
namespace net {
// 静态常量初始化
const int Channel::kNoneEvent = 0;
const int Channel::kReadEvent = EPOLLIN | EPOLLPRI;
const int Channel::kWriteEvent = EPOLLOUT;
    
Channel::Channel(EventLoop* loop, int fd)
    : _loop(loop), _fd(fd), _events(0), _revents(0)
{}

Channel::~Channel() {}
    
void Channel::update()
{
    _loop->updateEvent(this);
}
    
void Channel::remove()
{
    _loop->removeEvent(this);
}

/**
 * Connection中注册了Channel对应的回调函数，
 * 传入的回调函数均为Connection中对象的成员方法
 * 因此可以说明一点就是：Channel的结束一定晚于TcpConnection对象！
 * 此处用tie去解决TcpConnection和Channel的生命周期时长问题，
 * 从而保证了Channel对象能够在Connection销毁前销毁。
 **/
void Channel::tie(const std::shared_ptr<void>& obj)
{
    _tie = obj;
    _tied = true;
}
    
void Channel::handleEvent()
{
    if (_tied)
    {
        // 将weak_ptr提升为share_ptr，确保在事件处理期间Channel不会被销毁
        std::shared_ptr<void> guard = _tie.lock();
        if (guard)
        {
            handleEventWithGuard();
        }
         // 如果提升失败了 就不做任何处理 说明Channel的TcpConnection对象已经不存在了
    }
    else
    {
        handleEventWithGuard();
    }
}
    
    
void Channel::handleEventWithGuard()
{
    LOG_DEBUG("Channel handleEvent revents: %d", _revents);
        
    // 处理HUP事件(优先处理关闭事件)
    if ((_revents & EPOLLHUP) && !(_revents & EPOLLIN))
    {
        if (_closeCallback) _closeCallback();
    }
    
    // 处理错误事件
    if (_revents & EPOLLERR)
    {
        if (_errorCallback) _errorCallback();
    }
    
    // 处理可读事件(EPOLLIN:普通数据可读 EPOLLPRI:带外数据可读)
    if (_revents & (EPOLLIN | EPOLLPRI | EPOLLRDHUP))
    {
        if (_readCallback) _readCallback();
    }
    
    // 处理可写事件
    if (_revents & EPOLLOUT)
    {
        if (_writeCallback) _writeCallback();
    }
    
    // 调用通用事件回调(如果设置了)
    if (_eventCallback)
    {
        _eventCallback();
    }
}   

} // namespace net